home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
007
/
xlisp2.arc
/
XLMATH.C
< prev
next >
Wrap
Text File
|
1985-01-01
|
6KB
|
317 lines
/* xlmath - xlisp builtin arithmetic functions */
#include "xlisp.h"
/* external variables */
extern NODE *xlstack;
extern NODE *true;
/* forward declarations */
FORWARD NODE *unary();
FORWARD NODE *binary();
FORWARD NODE *predicate();
FORWARD NODE *compare();
/* xadd - builtin function for addition */
NODE *xadd(args)
NODE *args;
{
return (binary(args,'+'));
}
/* xsub - builtin function for subtraction */
NODE *xsub(args)
NODE *args;
{
return (binary(args,'-'));
}
/* xmul - builtin function for multiplication */
NODE *xmul(args)
NODE *args;
{
return (binary(args,'*'));
}
/* xdiv - builtin function for division */
NODE *xdiv(args)
NODE *args;
{
return (binary(args,'/'));
}
/* xrem - builtin function for remainder */
NODE *xrem(args)
NODE *args;
{
return (binary(args,'%'));
}
/* xmin - builtin function for minimum */
NODE *xmin(args)
NODE *args;
{
return (binary(args,'m'));
}
/* xmax - builtin function for maximum */
NODE *xmax(args)
NODE *args;
{
return (binary(args,'M'));
}
/* xbitand - builtin function for bitwise and */
NODE *xbitand(args)
NODE *args;
{
return (binary(args,'&'));
}
/* xbitior - builtin function for bitwise inclusive or */
NODE *xbitior(args)
NODE *args;
{
return (binary(args,'|'));
}
/* xbitxor - builtin function for bitwise exclusive or */
NODE *xbitxor(args)
NODE *args;
{
return (binary(args,'^'));
}
/* binary - handle binary operations */
LOCAL NODE *binary(args,fcn)
NODE *args; int fcn;
{
int ival,iarg;
NODE *val;
/* get the first argument */
ival = xlmatch(INT,&args)->n_int;
/* treat '-' with a single argument as a special case */
if (fcn == '-' && args == NULL)
ival = -ival;
/* handle each remaining argument */
while (args) {
/* get the next argument */
iarg = xlmatch(INT,&args)->n_int;
/* accumulate the result value */
switch (fcn) {
case '+': ival += iarg; break;
case '-': ival -= iarg; break;
case '*': ival *= iarg; break;
case '/': ival /= iarg; break;
case '%': ival %= iarg; break;
case 'M': if (iarg > ival) ival = iarg; break;
case 'm': if (iarg < ival) ival = iarg; break;
case '&': ival &= iarg; break;
case '|': ival |= iarg; break;
case '^': ival ^= iarg; break;
}
}
/* initialize value */
val = newnode(INT);
val->n_int = ival;
/* return the result value */
return (val);
}
/* xbitnot - bitwise not */
NODE *xbitnot(args)
NODE *args;
{
return (unary(args,'~'));
}
/* xabs - builtin function for absolute value */
NODE *xabs(args)
NODE *args;
{
return (unary(args,'A'));
}
/* xadd1 - builtin function for adding one */
NODE *xadd1(args)
NODE *args;
{
return (unary(args,'+'));
}
/* xsub1 - builtin function for subtracting one */
NODE *xsub1(args)
NODE *args;
{
return (unary(args,'-'));
}
/* unary - handle unary operations */
LOCAL NODE *unary(args,fcn)
NODE *args; int fcn;
{
NODE *val;
int ival;
/* get the argument */
ival = xlmatch(INT,&args)->n_int;
xllastarg(args);
/* compute the result */
switch (fcn) {
case '~': ival = ~ival; break;
case 'A': if (ival < 0) ival = -ival; break;
case '+': ival++; break;
case '-': ival--; break;
}
/* convert the value */
val = newnode(INT);
val->n_int = ival;
/* return the result value */
return (val);
}
/* xminusp - is this number negative? */
NODE *xminusp(args)
NODE *args;
{
return (predicate(args,'-'));
}
/* xzerop - is this number zero? */
NODE *xzerop(args)
NODE *args;
{
return (predicate(args,'Z'));
}
/* xplusp - is this number positive? */
NODE *xplusp(args)
NODE *args;
{
return (predicate(args,'+'));
}
/* xevenp - is this number even? */
NODE *xevenp(args)
NODE *args;
{
return (predicate(args,'E'));
}
/* xoddp - is this number odd? */
NODE *xoddp(args)
NODE *args;
{
return (predicate(args,'O'));
}
/* predicate - handle a predicate function */
LOCAL NODE *predicate(args,fcn)
NODE *args; int fcn;
{
NODE *val;
int ival;
/* get the argument */
ival = xlmatch(INT,&args)->n_int;
xllastarg(args);
/* compute the result */
switch (fcn) {
case '-': ival = (ival < 0); break;
case 'Z': ival = (ival == 0); break;
case '+': ival = (ival > 0); break;
case 'E': ival = ((ival & 1) == 0); break;
case 'O': ival = ((ival & 1) != 0); break;
}
/* return the result value */
return (ival ? true : NULL);
}
/* xlss - builtin function for < */
NODE *xlss(args)
NODE *args;
{
return (compare(args,'<'));
}
/* xleq - builtin function for <= */
NODE *xleq(args)
NODE *args;
{
return (compare(args,'L'));
}
/* equ - builtin function for = */
NODE *xequ(args)
NODE *args;
{
return (compare(args,'='));
}
/* xneq - builtin function for /= */
NODE *xneq(args)
NODE *args;
{
return (compare(args,'#'));
}
/* xgeq - builtin function for >= */
NODE *xgeq(args)
NODE *args;
{
return (compare(args,'G'));
}
/* xgtr - builtin function for > */
NODE *xgtr(args)
NODE *args;
{
return (compare(args,'>'));
}
/* compare - common compare function */
LOCAL NODE *compare(args,fcn)
NODE *args; int fcn;
{
NODE *arg1,*arg2;
int cmp;
/* get the two arguments */
arg1 = xlarg(&args);
arg2 = xlarg(&args);
xllastarg(args);
/* do the compare */
if (stringp(arg1) && stringp(arg2))
cmp = strcmp(arg1->n_str,arg2->n_str);
else if (fixp(arg1) && fixp(arg2))
cmp = arg1->n_int - arg2->n_int;
else
cmp = arg1 - arg2;
/* compute result of the compare */
switch (fcn) {
case '<': cmp = (cmp < 0); break;
case 'L': cmp = (cmp <= 0); break;
case '=': cmp = (cmp == 0); break;
case '#': cmp = (cmp != 0); break;
case 'G': cmp = (cmp >= 0); break;
case '>': cmp = (cmp > 0); break;
}
/* return the result */
return (cmp ? true : NULL);
}